package com.aegis.gateway.filter;

import com.aegis.gateway.constants.FilterChainEnum;
import com.aegis.gateway.utils.AuthUtil;
import com.aegis.manage.api.dto.SysAppDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * @Author wuweixin
 *
 * @Version 1.0
 * @Descritube 上下文不一样，satoken的工具在当前类无效,不要使用
 */
@Slf4j
@Component
public class SignFilter extends BaseWebFilter {


    @Override
    public Mono<Void> doFilter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        AuthUtil.setContext(exchange);
        SysAppDTO appInfo = filterManageService.getAppInfo(exchange);
        return DataBufferUtils.join(request.getBody())
                .flatMap(dataBuffer -> {
                    byte[] bytes = new byte[dataBuffer.readableByteCount()];
                    dataBuffer.read(bytes);
                    DataBufferUtils.release(dataBuffer);
                    String requestBody = new String(bytes, StandardCharsets.UTF_8);

                    // 执行鉴权逻辑
                    AuthUtil.checkSignature(appInfo.getAppSecret(), requestBody);
                    AuthUtil.clearContext();

                    // 创建带有缓存请求体的装饰器
                    ServerHttpRequest decoratedRequest = new CachedBodyRequestDecorator(exchange.getRequest(), bytes);
                    return chain.filter(exchange.mutate().request(decoratedRequest).build());
                })
                .switchIfEmpty(Mono.defer(() -> {
                    if (AuthUtil.getContext() == null) {
                        return chain.filter(exchange);
                    }
                    // 执行鉴权逻辑
                    AuthUtil.checkSignature(appInfo.getAppSecret());
                    AuthUtil.clearContext();

                    // 创建空请求体的装饰器
                    ServerHttpRequest decoratedRequest = new CachedBodyRequestDecorator(exchange.getRequest(), new byte[0]);
                    return chain.filter(exchange.mutate().request(decoratedRequest).build());
                }));

    }


    @Override
    public int getOrder() {
        return FilterChainEnum.SIGN_FILTER.getOrder();
    }

    //请求体缓存装饰器
    static class CachedBodyRequestDecorator extends ServerHttpRequestDecorator {
        private final byte[] cachedBody;

        public CachedBodyRequestDecorator(ServerHttpRequest delegate, byte[] cachedBody) {
            super(delegate);
            this.cachedBody = cachedBody;
        }

        @Override
        public Flux<DataBuffer> getBody() {
            DataBufferFactory bufferFactory = new DefaultDataBufferFactory(); // 创建DataBufferFactory
            DataBuffer buffer = bufferFactory.wrap(cachedBody); // 使用工厂创建DataBuffer
            return Flux.just(buffer); // 将其转换为Flux流返回
        }
    }
}
